import axios from "axios";
import {LocalStorageUtil} from "./local-storage";
import {router} from "../router";
class Http {
    private baseUrl: string = import.meta.env.VITE_BASE_URL + '/';
    private instances: Map<string, any> = new Map();
    public static DEFAULT: string = 'VERIFY_LOGIN';
    constructor() {
        this.instances.set(Http.DEFAULT, this.initVerifyLoginInstance());
    }

    /**
     * 初始化需要验证登陆的Axios请求实例
     * @private
     */
    private initVerifyLoginInstance() {
        let instance = axios.create({
            baseURL: this.baseUrl,
            timeout: 10000,
            headers: {},
            responseType: "json"
        });
        instance.interceptors.request.use(config => {
            let token = LocalStorageUtil.getToken() ;
            if (token) {
                config.headers.set("Authorization", "Bearer " + token.data)
            }
            console.log('request config', config);
            return config;
        }, error => {
            return Promise.reject(error);
        })
        instance.interceptors.response.use( response => {
            return response;
        }, error => {
            // Any status codes that falls outside the range of 2xx cause this function to trigger
            // Do something with response error
            if (error.response.status === 403) {
                router.push("/login");
            }
            return Promise.reject(error);
        });
        return instance;
    }

    public openFile(url: string, data: any) {
        const _url = this.convertURL(url, data)
        console.log("Open URL", this.baseUrl , _url)
        window.open(this.baseUrl.substring(0, this.baseUrl.length - 1) + _url, '_blank')
    }

    public getBaseUrl() {
        return this.baseUrl;
    }

    public get(url: string, data?: any, config?: any, instanceType?: string): Promise<any> {
        return this.request(url, "GET", data, config, instanceType);
    }

    public post(url: string, data?: any, config?: any, instanceType?: string): Promise<any> {
        return this.request(url, "POST", data, config, instanceType);
    }

    public delete(url: string, data?: any, config?: any, instanceType?: string): Promise<any> {
        return this.request(url, "DELETE", data, config, instanceType);
    }

    public put(url: string, data?: any, config?: any, instanceType?: string): Promise<any> {
        return this.request(url, "PUT", data, config, instanceType);
    }

    private request(url: string, method: string, data?: object, config?: any, instanceType?: string): Promise<any> {
        instanceType = instanceType ?? Http.DEFAULT;
        let instance = this.instances.get(instanceType)
        if (instance) {
            switch (method) {
                case "GET":
                    return instance.get(this.convertURL(url, data), config);
                case "POST":
                    if (!config || !config.headers || !config.headers["Content-Type"]) {
                        config = {headers: {"Content-Type": "multipart/form-data"}}
                    }
                    return instance.post(url, data, config);
                case "DELETE":
                    return instance.delete(this.convertURL(url, data), config);
                case "PUT":
                    return instance.put(url, data, config);
                default:
                    throw new Error('Request method not supported');
            }
        } else {
            throw new Error('Instance does not exist');
        }
    }

    private convertURL(url: string, param?: any): string {
        if (param) {
            const queryStr = Object.keys(param)
                .map(key => param[key] && `${encodeURIComponent(key)}=${encodeURIComponent(param[key])}`)
                .join('&');
            return url + `?${queryStr}`;
        } else {
            return url;
        }
    }
}


export const HttpService = new Http();